Libraries

We load the packages relevant for the exercise.

library(FactoMineR)
library(tidyr)
library(dplyr)
library(tidyverse)
library(magrittr)
library(ggplot2)
library(ggpubr)
library(factoextra)
library(gridExtra)
library(moments)

Screw Caps Data

The data ScrewCap.csv contains 195 lots of screw caps described by 11 variables. Diameter, weight, length are the physical characteristics of the cap; nb.of.pieces corresponds to the number of elements of the cap (the picture above corresponds to a cap with 2 pieces: the valve (clapet) is made of a different material); Mature.volume corresponds to the number of caps ordered and bought by the compagny (number in the lot).

summary(raw_data)
       Supplier      Diameter          weight       nb.of.pieces        Shape     Impermeability        Finishing   Mature.Volume    Raw.Material     Price            Length      
 Supplier A: 31   Min.   :0.4458   Min.   :0.610   Min.   : 2.000   Shape 1:134   Type 1:172     Hot Printing: 62   Min.   :  1000   ABS: 21      Min.   : 6.477   Min.   : 3.369  
 Supplier B:150   1st Qu.:0.7785   1st Qu.:1.083   1st Qu.: 3.000   Shape 2: 45   Type 2: 23     Lacquering  :133   1st Qu.: 15000   PP :148      1st Qu.:11.807   1st Qu.: 6.161  
 Supplier C: 14   Median :1.0120   Median :1.400   Median : 4.000   Shape 3:  8                                     Median : 45000   PS : 26      Median :14.384   Median : 8.086  
                  Mean   :1.2843   Mean   :1.701   Mean   : 4.113   Shape 4:  8                                     Mean   : 96930                Mean   :16.444   Mean   :10.247  
                  3rd Qu.:1.2886   3rd Qu.:1.704   3rd Qu.: 5.000                                                   3rd Qu.:115000                3rd Qu.:18.902   3rd Qu.:10.340  
                  Max.   :5.3950   Max.   :7.112   Max.   :10.000                                                   Max.   :800000                Max.   :46.610   Max.   :43.359  

2) We start with univariate and bivariate descriptive statistics. Using appropriate plot(s) or summaries answer the following questions.

a) How is the distribution of the Price? Comment your plot with respect to the quartiles of the Price.

From the quantile data, the summary statistics are given by: median, 1Q and 3Q as 14.432, 11.864 and 19.04 respectively.

The plots, the kurtosis and the skewness parameters suggest the price follows a bimodal distribution that is “skewed right”. The major mode is around 14 and the antimode is around 29. Furthermore, 50% of the prices in the range 11.864 and 19.04. This is consistent with graph where the majority of the density is concentrated inside this range and a long right tail of prices outside.

The boxplot supports this analyis and suggests the values in the tail are outliers.

price_density <- ggdensity(raw_data,x="Price",y = "..count..",
                        color="darkblue",
                        fill="lightblue",size=0.5, 
                        alpha=0.2, 
                        title = "Screw Cap Price Distribution", 
                        linetype = "solid", add = c("median"))+ font("title", size = 12,face="bold")
  
  
price_boxplot <- ggboxplot(raw_data$Price, width = 0.1, fill ="lightgray", outlier.colour = "darkblue", outlier.shape=4.2, ylab = "Price", xlab = "Screw Caps" , title = "Price Box Plot") + rotate() + font("title", size = 12,face="bold")
price_quantile <- quantile(raw_data$Price)
ggarrange(price_density, price_boxplot, ncol = 1, nrow = 2)

price_quantile
       0%       25%       50%       75%      100% 
 6.477451 11.863612 14.431594 19.039530 46.610372 
skewness(raw_data$Price)
[1] 1.682063
kurtosis(raw_data$Price)
[1] 6.300995

b) Does the Price depend on the Length? weight?

We examine Price vs. Length, log(Price) vs. log(Length); Price vs. weight, log(Price) vs. log(weight) and provide the summary for each.

The plots suggest somewhat of a relationship between the variables, but observing the R-sqaured values and the results of the F and T tests confirm this to a high degree of significance.

summary(lm(formula = Price ~ Length, raw_data))

Call:
lm(formula = Price ~ Length, data = raw_data)

Residuals:
    Min      1Q  Median      3Q     Max 
-13.901  -2.854  -0.741   1.931  16.181 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)  8.94613    0.50918   17.57   <2e-16 ***
Length       0.73168    0.03953   18.51   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 4.308 on 193 degrees of freedom
Multiple R-squared:  0.6397,    Adjusted R-squared:  0.6378 
F-statistic: 342.6 on 1 and 193 DF,  p-value: < 2.2e-16

c) Does the Price depend on the Impermeability? Shape?

Concerning Impermeability, the plots below show that there are some striking differences between the price distribution for Type 1 and Type 2, in particular observing the medians and the IQR.

Concerning Shapes, it is difficult to make any real conclusions regarding shape 3 and shape 4 given there are so few data points. We turn our attention to Shape 1 and Shape 2 - the IQR for these two shapes are seemingly different. This is confirmed by the result of the T Test.

summary(lm(Price~ Shape, data=raw_data))

Call:
lm(formula = Price ~ Shape, data = raw_data)

Residuals:
    Min      1Q  Median      3Q     Max 
-11.098  -3.850  -1.025   3.055  25.587 

Coefficients:
             Estimate Std. Error t value Pr(>|t|)    
(Intercept)   14.2006     0.5406  26.267  < 2e-16 ***
ShapeShape 2   8.1403     1.0782   7.550 1.75e-12 ***
ShapeShape 3   1.4510     2.2777   0.637  0.52485    
ShapeShape 4   7.4393     2.2777   3.266  0.00129 ** 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 6.258 on 191 degrees of freedom
Multiple R-squared:  0.2475,    Adjusted R-squared:  0.2357 
F-statistic: 20.94 on 3 and 191 DF,  p-value: 9.008e-12

d) Which is the less expensive Supplier?

The answer to this question depends on the definition of expensive.

First, examine the following absolute metrics (this can be seen via the boxplot) 1) Absolute price - Supplier B cheapest (6.477451). However, Supplier B is also the supplier which has the highest absolute price (46.610372) 2) Average Price - Supplier C cheapest (14.88869)

Second, examine the following relative metrics:
3) Average Price / Unit Length - Supplier A (1.505043) 4) Average Price / Unit weight - Supplier A (9.013902) 5) Average Price / Unit Diameter - Supplier A (11.95632)

The result above suggest Supplier A has the cheapest average price per unit of production.

The analysis however is not complete given we do not have a definition of cheapest price. Even the scatter and box plots below suggest suppliers may cater to specific product ranges. It also ignores the categorical data which could provide some insights into cheapest price for certain product features Furthermore, we have not performed statistical tests to examine the significance of these differences.

supplier_plot_1 <- ggboxplot(raw_data,x="Supplier",y="Price",color = "Supplier", palette = c("darkblue","red","darkgreen"),legend="none") + rotate()
supplier_plot_2 <- ggscatter(raw_data,x="Length",y="Price",color = "Supplier", palette = c("darkblue","red","darkgreen"),xscale= "log10", yscale="log10")
supplier_plot_3 <- ggscatter(raw_data,x="weight",y="Price",color = "Supplier", palette = c("darkblue","red","darkgreen"),xscale= "log10", yscale="log10")
supplier_plot_4 <- ggscatter(raw_data,x="Diameter",y="Price",color = "Supplier", palette = c("darkblue","red","darkgreen"),xscale= "log10", yscale="log10")
supplier_statistics <- raw_data %>% group_by(Supplier) %>%  summarise( "Average Price" = mean(Price), "Average Length" = mean(Length),"Average weight" = mean(weight),"Average Diameter" = mean(Diameter),  "Average Price / Length" = mean(Price)/mean(Length), "Average Price / weight" = mean(Price)/mean(weight), "Average Price / Diameter" = mean(Price)/mean(Diameter))
supplier_plot_1

supplier_plot_2

supplier_plot_3

supplier_plot_4

head(supplier_statistics)

3) One important point in explanatory data analysis consists in identifying potential outliers. Could you give points which are suspect regarding the Mature.Volume variable? Give the characteristics (other features) of the observations that seem suspsect

There are four data points which seem suspect - they have the same characteristics for Diameter, weight, nb.of.pieces, Impermeability, Finishing, Raw.Material and Mature.Volume. They differ in their supplier, price and length. These suggest some error in collating the data (system error / default data).

Mature.Volume_plot <- gghistogram(raw_data,x="Mature.Volume",y="..count..", color = "darkblue", fill = "lightgrey") + theme_minimal()
Using `bins = 30` by default. Pick better value with the argument `bins`.
Mature.Volume_plot

raw_data %>% filter (Mature.Volume > 6e+05 ) 

For the rest of the analysis, the 4 data points above are disregarded.

library(dplyr)
raw_data <- raw_data %>% filter (Mature.Volume < 6e+05 )

We will quickly check that there are no other noticeable outliers - this is indeed the case.

4) Perform a PCA on the dataset ScrewCap, explain briefly what are the aims of a PCA and how categorical variables are handled?

Principal components analysis (PCA) is a technique for taking high-dimensional data, and using the dependencies between the variables to represent it in a more tractable, lower-dimensional form, without losing too much information - we try capture the essence of high dimentional data in a low dimensional representation. The aim of PCA is to draw conclusions from the linear relationships between variables by detecting the principal dimensions of variability. This may be for compression, denoising, data completion, anomaly detection or for preprocessing before supervised learning (improve performance / regularization to reduce overfitting).

The categorical variables cannot be represented in the same way as the supplementary quantitative variables since it is not possible to calculate the correlation between a categorical variable and the principal components. The categorical variables here are handled as supplemetary variables on a purely illustrative basis - they are not used to calculate the distance between inidividuals. We represent a categorical variable at the barycentre of all the individuals possessing that variable. A categorical variable on the PCA performed below can therefore be regarded as the mean individual obtained from the set of individuals who have it.

Given our ultimate goal here is to explore data prior to a multiple regression, it is advisable to choose the explanatory variables for the regression model as active variables for PCA, and to project the variable to be explained (the dependent variable) as a supplementary variable. This gives some idea of the relationships between explanatory variables and thus of the need to select explanatory variables. This also gives us an idea of the quality of the regression: if the dependent variable is appropriately projected, it will be a well-fitted model. Thus we select Price as a supplementary variable.

The dataset in this exercise contains 6 supplementary variables: - 1 quantitative variable (Price) - 5 qualitative variables (Supplier, Shape, Impermeability and Finishing).

res.pca <- PCA(raw_data,quali.sup = c(1,5,6,7,9),quanti.sup = 10, graph = FALSE)
fviz_pca_ind(res.pca, col.ind="cos2", label=c("quali"), geom = "point", title = "Individual factor map (PCA)", habillage = "none") + scale_color_gradient2(low="lightblue", mid="blue", high="darkblue", midpoint=0.6) + theme_minimal() 

plot.PCA(res.pca,choix = c("ind"),invisible = c("ind"))+theme_minimal()
NULL

plot.PCA(res.pca,choix = c("var"))+theme_minimal()
NULL

5) Compute the correlation matrix between the variables and comment it with respect to the correlation circle

The first task is to center and standardize the variables. Then the correlation matrix is computed. All variable vectors are quite near to the boundary of the correlation circle on the variables plot - thus the variables are relatively well projected on the 2 dimensional subspace. We now turn our attention to correlations between variables.

The correlations can be visualised through the angles between variables on the correlation matrix. This can be related to the correlation matrix: - Diameter, Length and weight expose very strong corrleation: the angle between them is close to 0, suggesting correlation close to 1. These are all very highly correlated to the first Principal Component. - The three variables above are at an angle sightly wider than a right angle to both nb.of.pieces and Mature.Volume in the cirlce which suggests slightly negative correlation. - Price is highlighly correlatd to the three variables above - Equally, Mature.Volume and nb.of.pieces are at a slightly wider angle than a right angle which suggests slightly negative correlation.

Mature Volume and Number of Pieces are well projected on the 2nd dimensional subspace and then are not really correlated to Lenght, weight, Price and Diameter. Plus, we notice that Mature Volume and Number of Pieces are negatively correlated which means that when the more pieces we have for a product the less the compagny command this kind of product. This correlations are well explained in the covariance matrix. The cells that correspond to a combinaison of highly correlated features have a cov higher than 0.9 and the cells that correspond to a combinaison of uncorrelated (orthogonal) features have a cov lower than 0.2 - 0.3.

The PCA focuses on the relationships between the continuous variables. In fact, the PCA compute the vectors which are the synthetic variables the most correlated to all the continuous variables. Then, its possible to study the projection of the observations/features on this vectors and discuss the link between them. The issue is that the PCA does not handle categorical variables to the computation of the synthetic vectors.

Let’s now focus on the individual factor map : The barycentre related to \(Impermeability = Type2\) and \(Raw.Material = PS\) are near to the first synthetic axe which means that this two categories Type2 and PS are highly correlated to this axe and then, given the previous analysis to Lenght, weight, price and diameter. In fact, for instance, we have seen that Type 2 have a higher price in average than Type 1. We can say also for example than a PS product is related to a high diameter.

don <- as.matrix(raw_data[,-c(1,5,6,7,9,10)]) %>% scale()
don_correlation <- cor(don)
don_correlation
                Diameter     weight nb.of.pieces Mature.Volume     Length
Diameter       1.0000000  0.9622544  -0.14869500   -0.29164724  0.9996963
weight         0.9622544  1.0000000  -0.16884367   -0.31321323  0.9627460
nb.of.pieces  -0.1486950 -0.1688437   1.00000000   -0.07462463 -0.1463770
Mature.Volume -0.2916472 -0.3132132  -0.07462463    1.00000000 -0.2936330
Length         0.9996963  0.9627460  -0.14637705   -0.29363295  1.0000000
plot.PCA(res.pca,choix = c("var"))+theme_minimal()
NULL

6) On what kind of relationship PCA focuses? Is it a problem?

PCA focuses on the linear relationships between continuous variables. Given complex links also exist, such as quadratic relationships, logarithmics, exponential functions, and so forth, this may seem restrictive, but in practice many relationships can be considered linear, at least for an initial approximation. However, there is obviously non-linear datasets for which PCA will have pitfalls (e.g. spiral dataset). Furthermore, in PCA categorical variables cannot be active variables, which can be restrictive.

7) Comment the PCA outputs

Comment the position of the categories Impermeability=type 2 and Raw.Material=PS.

The coordinates for Type 2 are (3.30430162 , 0.0020023422) for the first two principal components The coordinate for PS are (2.69084507 -0.2539199538) for the first two principal components

Both categories have a high coordinate for the first principal component. Given the correlation circle shows high correlation between the first component and price, diameter, length and weight, this suggest Type 2 and PS have high values for these variables.

res.pca$quali.sup$coord
                   Dim.1        Dim.2        Dim.3         Dim.4         Dim.5
Supplier A    0.54805992 -0.054566515 -0.214051234  0.0227636641  0.0058684306
Supplier B   -0.06543165 -0.125589918 -0.026949041  0.0018781980 -0.0006195266
Supplier C   -0.44356100  1.440695488  0.728281700 -0.0670085402 -0.0056067533
Shape 1      -0.42564773 -0.137916238 -0.214123559  0.0065253174 -0.0009308749
Shape 2       1.42726960  0.394279456  0.383010989 -0.0314353290  0.0018793388
Shape 3      -0.55969671 -0.332207048  0.059604995  0.1360698967 -0.0029996610
Shape 4      -0.55191919  0.355523978  1.265466019 -0.0652825793  0.0075550964
Type 1       -0.45031131 -0.001823621 -0.009194259  0.0008200692 -0.0005392760
Type 2        3.28923043  0.013320364  0.067158065 -0.0059900708  0.0039390597
Hot Printing -0.28600503 -0.037712714  0.192161713  0.0717729126 -0.0006010224
Lacquering    0.13745978  0.018125491 -0.092356792 -0.0344955084  0.0002888635
ABS           0.87599666  0.220028373 -0.581512708  0.0043591307 -0.0032513149
PP           -0.61062316  0.013651457  0.120658551  0.0042947466 -0.0005390562
PS            2.67437709 -0.253323291 -0.198579404 -0.0273071254  0.0056116038

Comment the percentage of inertia

Below we see the percentage of inertia explained by each component.

res.pca$eig
         eigenvalue percentage of variance cumulative percentage of variance
comp 1 3.1071215080           62.142430160                          62.14243
comp 2 1.0669070766           21.338141532                          83.48057
comp 3 0.7768681861           15.537363723                          99.01794
comp 4 0.0488056018            0.976112036                          99.99405
comp 5 0.0002976274            0.005952549                         100.00000
dimdesc(res.pca, axes = 1:1)
$Dim.1
$Dim.1$quanti
              correlation       p.value
Length          0.9853764 3.259183e-147
Diameter        0.9851090 1.784008e-146
weight          0.9774643 1.263294e-129
Price           0.7960132  4.472456e-43
nb.of.pieces   -0.2017085  5.139018e-03
Mature.Volume  -0.4118157  3.243173e-09

$Dim.1$quali
                      R2      p.value
Impermeability 0.4767041 2.203784e-28
Raw.Material   0.4309747 9.602186e-24
Shape          0.2024825 3.268025e-09

$Dim.1$category
          Estimate      p.value
Type 2   1.8697709 2.203784e-28
PS       1.6944602 3.078822e-20
Shape 2  1.4547681 6.874053e-11
ABS     -0.1039202 1.566216e-02
Shape 1 -0.3981492 5.692581e-07
PP      -1.5905400 1.465743e-20
Type 1  -1.8697709 2.203784e-28

Fisher test Variance

Comments the results and describe precisely one cluster – Add Fisher Test

The cluster 1 is made of individuals sharing : - high values for the variable Mature.Volume. - low values for the variables nb.of.pieces, Price, weight, Length and Diameter (variables are sorted from the weakest).

The cluster 2 is made of individuals sharing : - high values for the variable nb.of.pieces. - low values for the variables Mature.Volume, Diameter, Length, weight and Price (variables are sorted from the weakest).

The cluster 3 is made of individuals such as 89, 90, 131, 161, 163 and 164. This group is characterized by : - high values for the variables Length, Diameter, weight and Price (variables are sorted from the strongest). - low values for the variables nb.of.pieces and Mature.Volume (variables are sorted from the weakest).

If someone ask you why you have selected k components and not k + 1 or k − 1, what is your answer? (could you suggest a strategy to assess the stability of the approach? - are there many differences between the clustering obtained on k components or on the initial data)

res.pca <- PCA(raw_data,quali.sup = c(1,5,6,7,9),quanti.sup = 10,ncp=4)

res.hcpc <- HCPC(res.pca, nb.clust = -1)

res.pca <- PCA(raw_data,quali.sup = c(1,5,6,7,9),quanti.sup = 10,ncp=3)

res.hcpc <- HCPC(res.pca, nb.clust = -1)

res.pca <- PCA(raw_data,quali.sup = c(1,5,6,7,9),quanti.sup = 10,ncp=2)

res.hcpc <- HCPC(res.pca, nb.clust = -1)

res.hcpc <- HCPC(res.pca, nb.clust = -1, graph = FALSE)
Chi-squared approximation may be incorrectChi-squared approximation may be incorrectChi-squared approximation may be incorrectChi-squared approximation may be incorrect
res.hcpc <- HCPC(res.pca, nb.clust = -1, graph = FALSE)
Chi-squared approximation may be incorrectChi-squared approximation may be incorrectChi-squared approximation may be incorrectChi-squared approximation may be incorrect
res.hcpc
**Results for the Hierarchical Clustering on Principal Components**
   name                    description                                              
1  "$data.clust"           "dataset with the cluster of the individuals"            
2  "$desc.var"             "description of the clusters by the variables"           
3  "$desc.var$quanti.var"  "description of the cluster var. by the continuous var." 
4  "$desc.var$quanti"      "description of the clusters by the continuous var."     
5  "$desc.var$test.chi2"   "description of the cluster var. by the categorical var."
6  "$desc.axes$category"   "description of the clusters by the categories."         
7  "$desc.axes"            "description of the clusters by the dimensions"          
8  "$desc.axes$quanti.var" "description of the cluster var. by the axes"            
9  "$desc.axes$quanti"     "description of the clusters by the axes"                
10 "$desc.ind"             "description of the clusters by the individuals"         
11 "$desc.ind$para"        "parangons of each clusters"                             
12 "$desc.ind$dist"        "specific individuals"                                   
13 "$call"                 "summary statistics"                                     
14 "$call$t"               "description of the tree"                                
plot.HCPC(res.hcpc, choice = 'map', draw.tree = FALSE, title = '', select=c("12"))

res.pca <- PCA(raw_data,quali.sup = c(1,5,6,7,9),quanti.sup = 10,ncp=3)

res.hcpc <- HCPC(res.pca, nb.clust = -1, graph = FALSE)
Chi-squared approximation may be incorrectChi-squared approximation may be incorrectChi-squared approximation may be incorrectChi-squared approximation may be incorrect
res.hcpc
**Results for the Hierarchical Clustering on Principal Components**
   name                    description                                              
1  "$data.clust"           "dataset with the cluster of the individuals"            
2  "$desc.var"             "description of the clusters by the variables"           
3  "$desc.var$quanti.var"  "description of the cluster var. by the continuous var." 
4  "$desc.var$quanti"      "description of the clusters by the continuous var."     
5  "$desc.var$test.chi2"   "description of the cluster var. by the categorical var."
6  "$desc.axes$category"   "description of the clusters by the categories."         
7  "$desc.axes"            "description of the clusters by the dimensions"          
8  "$desc.axes$quanti.var" "description of the cluster var. by the axes"            
9  "$desc.axes$quanti"     "description of the clusters by the axes"                
10 "$desc.ind"             "description of the clusters by the individuals"         
11 "$desc.ind$para"        "parangons of each clusters"                             
12 "$desc.ind$dist"        "specific individuals"                                   
13 "$call"                 "summary statistics"                                     
14 "$call$t"               "description of the tree"                                

Characterization of each supplier

catdes(raw_data, num.var=1)
Chi-squared approximation may be incorrectChi-squared approximation may be incorrectChi-squared approximation may be incorrectChi-squared approximation may be incorrect
$test.chi2
                    p.value df
Raw.Material   9.049049e-05  4
Impermeability 1.088731e-02  2

$category
$category$`Supplier A`
                       Cla/Mod  Mod/Cla   Global      p.value    v.test
Raw.Material=PS       42.30769 37.93103 13.61257 0.0002998155  3.615459
Impermeability=Type 2 34.78261 27.58621 12.04188 0.0130149176  2.483361
Shape=Shape 2         26.66667 41.37931 23.56021 0.0213728107  2.301333
Raw.Material=ABS       0.00000  0.00000 10.99476 0.0254288561 -2.234825
Impermeability=Type 1 12.50000 72.41379 87.95812 0.0130149176 -2.483361

$category$`Supplier B`
                   Cla/Mod  Mod/Cla   Global     p.value    v.test
Raw.Material=ABS 100.00000 14.18919 10.99476 0.003330616  2.935453
Raw.Material=PS   57.69231 10.13514 13.61257 0.015928453 -2.410551
Shape=Shape 2     60.00000 18.24324 23.56021 0.002374481 -3.038894

$category$`Supplier C`
                 Cla/Mod Mod/Cla   Global    p.value   v.test
Raw.Material=PP 9.722222     100 75.39267 0.01626019 2.403023


$quanti.var
                  Eta2      P-value
nb.of.pieces 0.2137072 1.530822e-10

$quanti
$quanti$`Supplier A`
NULL

$quanti$`Supplier B`
                v.test Mean in category Overall mean sd in category Overall sd     p.value
nb.of.pieces -2.817845         3.959459     4.115183       1.240523   1.413225 0.004834708

$quanti$`Supplier C`
               v.test Mean in category Overall mean sd in category Overall sd      p.value
nb.of.pieces 6.345875         6.428571     4.115183       1.720228   1.413225 2.211654e-10


attr(,"class")
[1] "catdes" "list " 
catdes(raw_data, num.var=5)
Chi-squared approximation may be incorrectChi-squared approximation may be incorrectChi-squared approximation may be incorrectChi-squared approximation may be incorrect
$test.chi2
                    p.value df
Impermeability 2.873602e-16  3
Raw.Material   8.762044e-07  6
Finishing      1.040072e-02  3

$category
$category$`Shape 1`
                         Cla/Mod    Mod/Cla   Global      p.value    v.test
Impermeability=Type 1  76.785714 99.2307692 87.95812 1.043033e-11  6.800436
Raw.Material=PP        72.222222 80.0000000 75.39267 3.596432e-02  2.097331
Finishing=Lacquering   72.868217 72.3076923 67.53927 4.420603e-02  2.012132
Finishing=Hot Printing 58.064516 27.6923077 32.46073 4.420603e-02 -2.012132
Raw.Material=PS        30.769231  6.1538462 13.61257 3.360691e-05 -4.147538
Impermeability=Type 2   4.347826  0.7692308 12.04188 1.043033e-11 -6.800436

$category$`Shape 2`
                       Cla/Mod  Mod/Cla   Global      p.value    v.test
Impermeability=Type 2 95.65217 48.88889 12.04188 2.151940e-15  7.932260
Raw.Material=PS       69.23077 40.00000 13.61257 1.004609e-07  5.325888
Supplier=Supplier A   41.37931 26.66667 15.18325 2.137281e-02  2.301333
Supplier=Supplier B   18.24324 60.00000 77.48691 2.374481e-03 -3.038894
Raw.Material=PP       16.66667 53.33333 75.39267 2.022645e-04 -3.716171
Impermeability=Type 1 13.69048 51.11111 87.95812 2.151940e-15 -7.932260

$category$`Shape 3`
NULL

$category$`Shape 4`
                        Cla/Mod Mod/Cla   Global   p.value    v.test
Finishing=Hot Printing 9.677419      75 32.46073 0.0169336  2.388146
Finishing=Lacquering   1.550388      25 67.53927 0.0169336 -2.388146


$quanti.var
                    Eta2      P-value
Price         0.24285191 2.771217e-11
Diameter      0.23221716 9.994081e-11
Length        0.23112294 1.139178e-10
weight        0.19722569 5.965369e-09
nb.of.pieces  0.10533516 1.120672e-04
Mature.Volume 0.05693699 1.177220e-02

$quanti
$quanti$`Shape 1`
                v.test Mean in category Overall mean sd in category Overall sd      p.value
nb.of.pieces -3.721118         3.853846     4.115183      1.2716527  1.4132247 1.983430e-04
weight       -5.069026         1.418671     1.714121      0.7867181  1.1728539 3.998565e-07
Length       -5.469752         8.191771    10.329589      5.0759423  7.8647827 4.506649e-08
Diameter     -5.489199         1.026728     1.294639      0.6306647  0.9821218 4.037612e-08
Price        -6.344431        14.290942    16.552332      4.8726895  7.1724314 2.232495e-10

$quanti$`Shape 2`
                 v.test Mean in category Overall mean sd in category   Overall sd      p.value
Diameter       6.616403         2.143782     1.294639       1.409033 9.821218e-01 3.680436e-11
Length         6.603559        17.116281    10.329589      11.260640 7.864783e+00 4.014035e-11
Price          6.176070        22.340911    16.552332       9.620363 7.172431e+00 6.571699e-10
weight         6.118100         2.651800     1.714121       1.698673 1.172854e+00 9.469770e-10
nb.of.pieces   2.865929         4.644444     4.115183       1.607698 1.413225e+00 4.157871e-03
Mature.Volume -2.005008     58355.222222 82206.026178   68318.473831 9.103190e+04 4.496223e-02

$quanti$`Shape 3`
NULL

$quanti$`Shape 4`
                v.test Mean in category Overall mean sd in category   Overall sd     p.value
nb.of.pieces  3.078997          5.62500     4.115183   9.921567e-01     1.413225 0.002076987
Mature.Volume 2.629122     165250.00000 82206.026178   1.132649e+05 91031.901051 0.008560561
Price         2.044271         21.63988    16.552332   3.822103e+00     7.172431 0.040926790


attr(,"class")
[1] "catdes" "list " 
catdes(raw_data, num.var=6)
Chi-squared approximation may be incorrectChi-squared approximation may be incorrectChi-squared approximation may be incorrect
$test.chi2
                  p.value df
Raw.Material 4.088669e-21  2
Shape        2.873602e-16  3
Supplier     1.088731e-02  2

$category
$category$`Type 1`
                     Cla/Mod   Mod/Cla   Global      p.value    v.test
Shape=Shape 1       99.23077 76.785714 68.06283 1.043033e-11  6.800436
Raw.Material=PP     97.91667 83.928571 75.39267 1.773212e-11  6.723573
Supplier=Supplier A 72.41379 12.500000 15.18325 1.301492e-02 -2.483361
Raw.Material=PS     30.76923  4.761905 13.61257 5.429478e-15 -7.816541
Shape=Shape 2       51.11111 13.690476 23.56021 2.151940e-15 -7.932260

$category$`Type 2`
                       Cla/Mod   Mod/Cla   Global      p.value    v.test
Shape=Shape 2       48.8888889 95.652174 23.56021 2.151940e-15  7.932260
Raw.Material=PS     69.2307692 78.260870 13.61257 5.429478e-15  7.816541
Supplier=Supplier A 27.5862069 34.782609 15.18325 1.301492e-02  2.483361
Raw.Material=PP      2.0833333 13.043478 75.39267 1.773212e-11 -6.723573
Shape=Shape 1        0.7692308  4.347826 68.06283 1.043033e-11 -6.800436


$quanti.var
                    Eta2      P-value
Diameter      0.47062626 6.604215e-28
Length        0.46804072 1.049429e-27
weight        0.45675032 7.728264e-27
Price         0.43301606 4.512224e-25
Mature.Volume 0.07171395 1.801495e-04

$quanti
$quanti$`Type 1`
                 v.test Mean in category Overall mean sd in category   Overall sd      p.value
Mature.Volume  3.691294     91225.988095 82206.026178   9.338486e+04 9.103190e+04 2.231162e-04
Price         -9.070449        14.805996    16.552332   4.819967e+00 7.172431e+00 1.185272e-19
weight        -9.315716         1.420835     1.714121   6.707159e-01 1.172854e+00 1.211330e-20
Length        -9.430150         8.338742    10.329589   4.357114e+00 7.864783e+00 4.095012e-21
Diameter      -9.456161         1.045344     1.294639   5.411724e-01 9.821218e-01 3.194554e-21

$quanti$`Type 2`
                 v.test Mean in category Overall mean sd in category   Overall sd      p.value
Diameter       9.456161         3.115573     1.294639       1.449522 9.821218e-01 3.194554e-21
Length         9.430150        24.871426    10.329589      11.600832 7.864783e+00 4.095012e-21
weight         9.315716         3.856391     1.714121       1.708742 1.172854e+00 1.211330e-20
Price          9.070449        29.308174    16.552332       8.516118 7.172431e+00 1.185272e-19
Mature.Volume -3.691294     16321.086957 82206.026178   13496.587327 9.103190e+04 2.231162e-04


attr(,"class")
[1] "catdes" "list " 

res.hcpc.famd$call$X$Dim.1
  [1] -1.98063919 -1.83264787 -1.83106329 -1.78617733 -1.77810618 -1.76793474 -1.76710263 -1.75740608 -1.74971627 -1.74854492 -1.72234966 -1.66587800 -1.64757197 -1.64122934
 [15] -1.63598508 -1.56390795 -1.53944334 -1.53334618 -1.48308272 -1.38978669 -1.31431198 -1.31360993 -1.30659672 -1.30106267 -1.24853337 -1.22972350 -1.22095845 -1.21456405
 [29] -1.18418458 -1.18021014 -1.17935581 -1.17927296 -1.17545877 -1.16352170 -1.15631274 -1.15536248 -1.14893262 -1.14368481 -1.13904799 -1.11948077 -1.11592461 -1.11166467
 [43] -1.10864477 -1.07786759 -1.07465242 -1.07231358 -1.05375226 -1.03073238 -1.01177639 -1.00275909 -1.00244847 -0.99953402 -0.99685597 -0.99557798 -0.99270885 -0.98055457
 [57] -0.98041153 -0.97369797 -0.97319443 -0.96309915 -0.94797090 -0.93951350 -0.92381405 -0.92380588 -0.92312060 -0.92280368 -0.92215711 -0.91733190 -0.91127725 -0.90468216
 [71] -0.88924490 -0.88886587 -0.88556501 -0.87235273 -0.86644337 -0.86479528 -0.83275001 -0.81147499 -0.77426760 -0.77398705 -0.77256095 -0.76784626 -0.76735493 -0.76500699
 [85] -0.75906301 -0.74956767 -0.74385898 -0.72805741 -0.71957456 -0.70612214 -0.67838613 -0.67821432 -0.64991811 -0.64920144 -0.64269013 -0.63822303 -0.63582084 -0.63163680
 [99] -0.62753059 -0.62599476 -0.62186560 -0.60480936 -0.58138172 -0.57247016 -0.56818608 -0.55787880 -0.55368923 -0.54139477 -0.53854440 -0.53480620 -0.52898642 -0.52824415
[113] -0.52616669 -0.52564460 -0.52454183 -0.52449868 -0.51962886 -0.51480527 -0.50739799 -0.49352372 -0.48049116 -0.47854325 -0.47511958 -0.45213593 -0.44366084 -0.41417752
[127] -0.40516410 -0.39864924 -0.39340526 -0.38440624 -0.38336093 -0.38001794 -0.37853964 -0.35220981 -0.34431429 -0.32536820 -0.31982441 -0.31803255 -0.30039211 -0.28421095
[141] -0.28417967 -0.27830495 -0.27577096 -0.26247151 -0.25453002 -0.24784546 -0.23849067 -0.23173017 -0.23034051 -0.22769867 -0.15845660 -0.05646856 -0.05377382  0.05889003
[155]  0.07158955  0.07913132  0.16276548  0.79185578  1.06680161  1.09360971  1.14437872  1.21748198  1.25067158  1.37109701  2.03126674  2.20958460  2.25060435  2.48114155
[169]  2.49540111  2.51611986  2.68062272  3.05674906  3.07969012  3.23130366  3.77350671  3.80195508  4.13207845  4.32016658  4.35027614  4.72999750  5.26696337  5.37357116
[183]  5.86802720  5.87862818  6.58628131  6.60222800  6.60582995  7.20144721  7.28664755  7.39353843  7.91577973
LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKKipMaWJyYXJpZXMqKgoKV2UgbG9hZCB0aGUgcGFja2FnZXMgcmVsZXZhbnQgZm9yIHRoZSBleGVyY2lzZS4gCgpgYGB7cn0KCmxpYnJhcnkoRmFjdG9NaW5lUikKbGlicmFyeSh0aWR5cikKbGlicmFyeShkcGx5cikKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkobWFncml0dHIpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShnZ3B1YnIpCmxpYnJhcnkoZmFjdG9leHRyYSkKbGlicmFyeShncmlkRXh0cmEpCmxpYnJhcnkobW9tZW50cykKCmBgYAoKCioqU2NyZXcgQ2FwcyBEYXRhKioKClRoZSBkYXRhIFNjcmV3Q2FwLmNzdiBjb250YWlucyAxOTUgbG90cyBvZiBzY3JldyBjYXBzIGRlc2NyaWJlZCBieSAxMSB2YXJpYWJsZXMuIERpYW1ldGVyLCB3ZWlnaHQsIGxlbmd0aCBhcmUgdGhlIHBoeXNpY2FsIGNoYXJhY3RlcmlzdGljcyBvZiB0aGUgY2FwOyBuYi5vZi5waWVjZXMgY29ycmVzcG9uZHMgdG8gdGhlIG51bWJlciBvZiBlbGVtZW50cyBvZiB0aGUgY2FwICh0aGUgcGljdHVyZSBhYm92ZSBjb3JyZXNwb25kcyB0byBhIGNhcCB3aXRoIDIgcGllY2VzOiB0aGUgdmFsdmUgKGNsYXBldCkgaXMgbWFkZSBvZiBhIGRpZmZlcmVudCBtYXRlcmlhbCk7IE1hdHVyZS52b2x1bWUgY29ycmVzcG9uZHMgdG8gdGhlIG51bWJlciBvZiBjYXBzIG9yZGVyZWQgYW5kIGJvdWdodCBieSB0aGUgY29tcGFnbnkgKG51bWJlciBpbiB0aGUgbG90KS4KCmBgYHtyfQoKcmF3X2RhdGEgPC0gcmVhZC50YWJsZSgiU2NyZXdDYXBzLmNzdiIsaGVhZGVyPVRSVUUsIHNlcD0iLCIsIGRlYz0iLiIsIHJvdy5uYW1lcz0xKQpoZWFkKHJhd19kYXRhKQpkaW0ocmF3X2RhdGEpCnN1bW1hcnkocmF3X2RhdGEpCmBgYAoKKioyKSBXZSBzdGFydCB3aXRoIHVuaXZhcmlhdGUgYW5kIGJpdmFyaWF0ZSBkZXNjcmlwdGl2ZSBzdGF0aXN0aWNzLiBVc2luZyBhcHByb3ByaWF0ZSBwbG90KHMpIG9yIHN1bW1hcmllcyBhbnN3ZXIgdGhlIGZvbGxvd2luZyBxdWVzdGlvbnMuKioKCiphKSBIb3cgaXMgdGhlIGRpc3RyaWJ1dGlvbiBvZiB0aGUgUHJpY2U/IENvbW1lbnQgeW91ciBwbG90IHdpdGggcmVzcGVjdCB0byB0aGUgcXVhcnRpbGVzIG9mIHRoZSBQcmljZS4qCgpGcm9tIHRoZSBxdWFudGlsZSBkYXRhLCB0aGUgc3VtbWFyeSBzdGF0aXN0aWNzIGFyZSBnaXZlbiBieTogbWVkaWFuLCAxUSBhbmQgM1EgIGFzIDE0LjQzMiwgMTEuODY0IGFuZCAxOS4wNCByZXNwZWN0aXZlbHkuIAoKVGhlIHBsb3RzLCB0aGUga3VydG9zaXMgYW5kIHRoZSBza2V3bmVzcyBwYXJhbWV0ZXJzIHN1Z2dlc3QgdGhlIHByaWNlIGZvbGxvd3MgYSBiaW1vZGFsIGRpc3RyaWJ1dGlvbiB0aGF0IGlzICJza2V3ZWQgcmlnaHQiLiAKVGhlIG1ham9yIG1vZGUgaXMgYXJvdW5kIDE0IGFuZCB0aGUgYW50aW1vZGUgaXMgYXJvdW5kIDI5LiBGdXJ0aGVybW9yZSwgNTAlIG9mIHRoZSBwcmljZXMgaW4gdGhlIHJhbmdlIDExLjg2NCBhbmQgMTkuMDQuIFRoaXMgaXMgY29uc2lzdGVudCB3aXRoIGdyYXBoIHdoZXJlIHRoZSBtYWpvcml0eSBvZiB0aGUgZGVuc2l0eSBpcyBjb25jZW50cmF0ZWQgaW5zaWRlIHRoaXMgcmFuZ2UgYW5kIGEgbG9uZyByaWdodCB0YWlsIG9mIHByaWNlcyBvdXRzaWRlLiAKClRoZSBib3hwbG90IHN1cHBvcnRzIHRoaXMgYW5hbHlpcyBhbmQgc3VnZ2VzdHMgdGhlIHZhbHVlcyBpbiB0aGUgdGFpbCBhcmUgb3V0bGllcnMuIAoKYGBge3J9CgpwcmljZV9kZW5zaXR5IDwtIGdnZGVuc2l0eShyYXdfZGF0YSx4PSJQcmljZSIseSA9ICIuLmNvdW50Li4iLAogICAgICAgICAgICAgICAgICAgICAgICBjb2xvcj0iZGFya2JsdWUiLAogICAgICAgICAgICAgICAgICAgICAgICBmaWxsPSJsaWdodGJsdWUiLHNpemU9MC41LCAKICAgICAgICAgICAgICAgICAgICAgICAgYWxwaGE9MC4yLCAKICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGUgPSAiU2NyZXcgQ2FwIFByaWNlIERpc3RyaWJ1dGlvbiIsIAogICAgICAgICAgICAgICAgICAgICAgICBsaW5ldHlwZSA9ICJzb2xpZCIsIGFkZCA9IGMoIm1lZGlhbiIpKSsgZm9udCgidGl0bGUiLCBzaXplID0gMTIsZmFjZT0iYm9sZCIpCiAgCgogIAoKcHJpY2VfYm94cGxvdCA8LSBnZ2JveHBsb3QocmF3X2RhdGEkUHJpY2UsIHdpZHRoID0gMC4xLCBmaWxsID0ibGlnaHRncmF5Iiwgb3V0bGllci5jb2xvdXIgPSAiZGFya2JsdWUiLCBvdXRsaWVyLnNoYXBlPTQuMiwgeWxhYiA9ICJQcmljZSIsIHhsYWIgPSAiU2NyZXcgQ2FwcyIgLCB0aXRsZSA9ICJQcmljZSBCb3ggUGxvdCIpICsgcm90YXRlKCkgKyBmb250KCJ0aXRsZSIsIHNpemUgPSAxMixmYWNlPSJib2xkIikKCgoKcHJpY2VfcXVhbnRpbGUgPC0gcXVhbnRpbGUocmF3X2RhdGEkUHJpY2UpCgpnZ2FycmFuZ2UocHJpY2VfZGVuc2l0eSwgcHJpY2VfYm94cGxvdCwgbmNvbCA9IDEsIG5yb3cgPSAyKQoKcHJpY2VfcXVhbnRpbGUKc2tld25lc3MocmF3X2RhdGEkUHJpY2UpCmt1cnRvc2lzKHJhd19kYXRhJFByaWNlKQoKYGBgCgoKKmIpIERvZXMgdGhlIFByaWNlIGRlcGVuZCBvbiB0aGUgTGVuZ3RoPyB3ZWlnaHQ/KgoKV2UgZXhhbWluZSBQcmljZSB2cy4gTGVuZ3RoLCBsb2coUHJpY2UpIHZzLiBsb2coTGVuZ3RoKTsgUHJpY2UgdnMuIHdlaWdodCwgbG9nKFByaWNlKSB2cy4gbG9nKHdlaWdodCkgYW5kIHByb3ZpZGUgdGhlIHN1bW1hcnkgZm9yIGVhY2guIAoKVGhlIHBsb3RzIHN1Z2dlc3Qgc29tZXdoYXQgb2YgYSByZWxhdGlvbnNoaXAgYmV0d2VlbiB0aGUgdmFyaWFibGVzLCBidXQgb2JzZXJ2aW5nIHRoZSBSLXNxYXVyZWQgdmFsdWVzIGFuZCB0aGUgcmVzdWx0cyBvZiB0aGUgRiBhbmQgVCB0ZXN0cyBjb25maXJtIHRoaXMgdG8gYSBoaWdoIGRlZ3JlZSBvZiBzaWduaWZpY2FuY2UuIAoKYGBge3J9CnByaWNlX2xlbmd0aCA8LSBnZ3Bsb3QocmF3X2RhdGEsIGFlcyh4PUxlbmd0aCwgeT1QcmljZSkpICsgZ2VvbV9wb2ludCgpICsgZ2VvbV9zbW9vdGgobWV0aG9kPWxtLCBjb2xvcj0iZGFya2dyZWVuIikrIHRoZW1lX21pbmltYWwoKQpwcmljZV9sZW5ndGhfbG9nIDwtIGdncGxvdChyYXdfZGF0YSwgYWVzKHg9bG9nKExlbmd0aCksIHk9bG9nKFByaWNlKSkpICsgZ2VvbV9wb2ludCgpICsgZ2VvbV9zbW9vdGgobWV0aG9kPWxtLCBjb2xvcj0iZGFya2dyZWVuIikrIHRoZW1lX21pbmltYWwoKQpwcmljZV93ZWlnaHQgPC0gZ2dwbG90KHJhd19kYXRhLCBhZXMoeD13ZWlnaHQsIHk9UHJpY2UpKSArIGdlb21fcG9pbnQoKSArIGdlb21fc21vb3RoKG1ldGhvZD1sbSxjb2xvcj0icmVkIikrdGhlbWVfbWluaW1hbCgpCnByaWNlX3dlaWdodF9sb2cgPC0gZ2dwbG90KHJhd19kYXRhLCBhZXMoeD1sb2cod2VpZ2h0KSwgeT1sb2coUHJpY2UpKSkgKyBnZW9tX3BvaW50KCkgKyBnZW9tX3Ntb290aChtZXRob2Q9bG0sY29sb3I9InJlZCIpK3RoZW1lX21pbmltYWwoKQoKZ2dhcnJhbmdlKGdnYXJyYW5nZShwcmljZV9sZW5ndGgsIHByaWNlX2xlbmd0aF9sb2csIG5jb2wgPSAyLCBucm93ID0gMSksIGdnYXJyYW5nZShwcmljZV93ZWlnaHQsIHByaWNlX3dlaWdodF9sb2csIG5jb2wgPSAyLCBucm93ID0gMSksIG5jb2wgPSAxLCBucm93ID0gMikKCnN1bW1hcnkobG0oZm9ybXVsYSA9IFByaWNlIH4gTGVuZ3RoLCByYXdfZGF0YSkpCnN1bW1hcnkobG0oZm9ybXVsYSA9IGxvZyhQcmljZSkgfiBsb2coTGVuZ3RoKSwgcmF3X2RhdGEpKQpzdW1tYXJ5KGxtKGZvcm11bGEgPSBQcmljZSB+IHdlaWdodCwgcmF3X2RhdGEpKQpzdW1tYXJ5KGxtKGZvcm11bGEgPSBsb2coUHJpY2UpIH4gbG9nKHdlaWdodCksIHJhd19kYXRhKSkKYGBgCgoKKmMpIERvZXMgdGhlIFByaWNlIGRlcGVuZCBvbiB0aGUgSW1wZXJtZWFiaWxpdHk/IFNoYXBlPyogIAoKQ29uY2VybmluZyBJbXBlcm1lYWJpbGl0eSwgdGhlIHBsb3RzIGJlbG93IHNob3cgdGhhdCB0aGVyZSBhcmUgc29tZSBzdHJpa2luZyBkaWZmZXJlbmNlcyBiZXR3ZWVuIHRoZSBwcmljZSBkaXN0cmlidXRpb24gZm9yIFR5cGUgMSBhbmQgVHlwZSAyLCBpbiBwYXJ0aWN1bGFyIG9ic2VydmluZyB0aGUgbWVkaWFucyBhbmQgdGhlIElRUi4gCgpDb25jZXJuaW5nIFNoYXBlcywgaXQgaXMgZGlmZmljdWx0IHRvIG1ha2UgYW55IHJlYWwgY29uY2x1c2lvbnMgcmVnYXJkaW5nIHNoYXBlIDMgYW5kIHNoYXBlIDQgZ2l2ZW4gdGhlcmUgYXJlIHNvIGZldyBkYXRhIHBvaW50cy4gV2UgdHVybiBvdXIgYXR0ZW50aW9uIHRvIFNoYXBlIDEgYW5kIFNoYXBlIDIgLSB0aGUgSVFSIGZvciB0aGVzZSB0d28gc2hhcGVzIGFyZSBzZWVtaW5nbHkgZGlmZmVyZW50LiBUaGlzIGlzIGNvbmZpcm1lZCBieSB0aGUgcmVzdWx0IG9mIHRoZSBUIFRlc3QuIAoKCmBgYHtyfQppbXBlcm1hYmlsaXR5X3Bsb3RfMSA8LSBnZ2RvdHBsb3QocmF3X2RhdGEseD0iSW1wZXJtZWFiaWxpdHkiLHk9IlByaWNlIixjb2xvciA9ICJJbXBlcm1lYWJpbGl0eSIsIHBhbGV0dGUgPSAiamNvIixiaW53aWR0aCA9IDEsbGVnZW5kPSJub25lIikKc2hhcGVfcGxvdF8xIDwtIGdnZG90cGxvdChyYXdfZGF0YSx4PSJTaGFwZSIseT0iUHJpY2UiLGNvbG9yID0gIlNoYXBlIiwgcGFsZXR0ZSA9ICJucGciLGJpbndpZHRoID0gMSxsZWdlbmQ9Im5vbmUiKQppbXBlcm1hYmlsaXR5X3Bsb3RfMiA8LSBnZ2JveHBsb3QocmF3X2RhdGEseD0iSW1wZXJtZWFiaWxpdHkiLHk9IlByaWNlIixjb2xvciA9ICJJbXBlcm1lYWJpbGl0eSIsIHBhbGV0dGUgPSAiamNvIixsZWdlbmQ9Im5vbmUiKQpzaGFwZV9wbG90XzIgPC0gZ2dib3hwbG90KHJhd19kYXRhLHg9IlNoYXBlIix5PSJQcmljZSIsY29sb3IgPSAiU2hhcGUiLCBwYWxldHRlID0gIm5wZyIsIGxlZ2VuZCA9ICJub25lIikKCgpnZ2FycmFuZ2UoZ2dhcnJhbmdlKGltcGVybWFiaWxpdHlfcGxvdF8xLGltcGVybWFiaWxpdHlfcGxvdF8yLG5jb2wgPSAyLCBucm93ID0gMSksCiAgICAgICAgICAgZ2dhcnJhbmdlKHNoYXBlX3Bsb3RfMSxzaGFwZV9wbG90XzIsbmNvbCA9IDIsIG5yb3cgPSAxKSwKICAgICAgICAgICBuY29sID0gMSwgbnJvdyA9IDIpCgpzdW1tYXJ5KGxtKFByaWNlfiBJbXBlcm1lYWJpbGl0eSwgZGF0YT1yYXdfZGF0YSkpCnN1bW1hcnkobG0oUHJpY2V+IFNoYXBlLCBkYXRhPXJhd19kYXRhKSkKCmBgYAoKKmQpIFdoaWNoIGlzIHRoZSBsZXNzIGV4cGVuc2l2ZSBTdXBwbGllcj8qCgpUaGUgYW5zd2VyIHRvIHRoaXMgcXVlc3Rpb24gZGVwZW5kcyBvbiB0aGUgZGVmaW5pdGlvbiBvZiBleHBlbnNpdmUuIAoKRmlyc3QsIGV4YW1pbmUgdGhlIGZvbGxvd2luZyBhYnNvbHV0ZSBtZXRyaWNzICh0aGlzIGNhbiBiZSBzZWVuIHZpYSB0aGUgYm94cGxvdCkKMSkgQWJzb2x1dGUgcHJpY2UgLSBTdXBwbGllciBCIGNoZWFwZXN0ICg2LjQ3NzQ1MSkuIEhvd2V2ZXIsIFN1cHBsaWVyIEIgaXMgYWxzbyB0aGUgc3VwcGxpZXIgd2hpY2ggaGFzIHRoZSBoaWdoZXN0IGFic29sdXRlIHByaWNlICg0Ni42MTAzNzIpCjIpIEF2ZXJhZ2UgUHJpY2UgLSBTdXBwbGllciBDIGNoZWFwZXN0ICgxNC44ODg2OSkKClNlY29uZCwgZXhhbWluZSB0aGUgZm9sbG93aW5nIHJlbGF0aXZlIG1ldHJpY3M6ICAKMykgQXZlcmFnZSBQcmljZSAvIFVuaXQgTGVuZ3RoIC0gU3VwcGxpZXIgQSAoMS41MDUwNDMpCjQpIEF2ZXJhZ2UgUHJpY2UgLyBVbml0IHdlaWdodCAtIFN1cHBsaWVyIEEgKDkuMDEzOTAyKQo1KSBBdmVyYWdlIFByaWNlIC8gVW5pdCBEaWFtZXRlciAtIFN1cHBsaWVyIEEgKDExLjk1NjMyKQoKVGhlIHJlc3VsdCBhYm92ZSBzdWdnZXN0IFN1cHBsaWVyIEEgaGFzIHRoZSBjaGVhcGVzdCBhdmVyYWdlIHByaWNlIHBlciB1bml0IG9mIHByb2R1Y3Rpb24uCgpUaGUgYW5hbHlzaXMgaG93ZXZlciBpcyBub3QgY29tcGxldGUgZ2l2ZW4gd2UgZG8gbm90IGhhdmUgYSBkZWZpbml0aW9uIG9mIGNoZWFwZXN0IHByaWNlLiBFdmVuIHRoZSBzY2F0dGVyIGFuZCBib3ggcGxvdHMgYmVsb3cgc3VnZ2VzdCBzdXBwbGllcnMgbWF5IGNhdGVyIHRvIHNwZWNpZmljIHByb2R1Y3QgcmFuZ2VzLiBJdCBhbHNvIGlnbm9yZXMgdGhlIGNhdGVnb3JpY2FsIGRhdGEgd2hpY2ggY291bGQgcHJvdmlkZSBzb21lIGluc2lnaHRzIGludG8gY2hlYXBlc3QgcHJpY2UgZm9yIGNlcnRhaW4gcHJvZHVjdCBmZWF0dXJlcyBGdXJ0aGVybW9yZSwgd2UgaGF2ZSBub3QgcGVyZm9ybWVkICBzdGF0aXN0aWNhbCB0ZXN0cyB0byBleGFtaW5lIHRoZSBzaWduaWZpY2FuY2Ugb2YgdGhlc2UgZGlmZmVyZW5jZXMuIAoKYGBge3J9CgpzdXBwbGllcl9wbG90XzEgPC0gZ2dib3hwbG90KHJhd19kYXRhLHg9IlN1cHBsaWVyIix5PSJQcmljZSIsY29sb3IgPSAiU3VwcGxpZXIiLCBwYWxldHRlID0gYygiZGFya2JsdWUiLCJyZWQiLCJkYXJrZ3JlZW4iKSxsZWdlbmQ9Im5vbmUiKSArIHJvdGF0ZSgpCnN1cHBsaWVyX3Bsb3RfMiA8LSBnZ3NjYXR0ZXIocmF3X2RhdGEseD0iTGVuZ3RoIix5PSJQcmljZSIsY29sb3IgPSAiU3VwcGxpZXIiLCBwYWxldHRlID0gYygiZGFya2JsdWUiLCJyZWQiLCJkYXJrZ3JlZW4iKSx4c2NhbGU9ICJsb2cxMCIsIHlzY2FsZT0ibG9nMTAiKQpzdXBwbGllcl9wbG90XzMgPC0gZ2dzY2F0dGVyKHJhd19kYXRhLHg9IndlaWdodCIseT0iUHJpY2UiLGNvbG9yID0gIlN1cHBsaWVyIiwgcGFsZXR0ZSA9IGMoImRhcmtibHVlIiwicmVkIiwiZGFya2dyZWVuIikseHNjYWxlPSAibG9nMTAiLCB5c2NhbGU9ImxvZzEwIikKc3VwcGxpZXJfcGxvdF80IDwtIGdnc2NhdHRlcihyYXdfZGF0YSx4PSJEaWFtZXRlciIseT0iUHJpY2UiLGNvbG9yID0gIlN1cHBsaWVyIiwgcGFsZXR0ZSA9IGMoImRhcmtibHVlIiwicmVkIiwiZGFya2dyZWVuIikseHNjYWxlPSAibG9nMTAiLCB5c2NhbGU9ImxvZzEwIikKCnN1cHBsaWVyX3N0YXRpc3RpY3MgPC0gcmF3X2RhdGEgJT4lIGdyb3VwX2J5KFN1cHBsaWVyKSAlPiUgIHN1bW1hcmlzZSggIkF2ZXJhZ2UgUHJpY2UiID0gbWVhbihQcmljZSksICJBdmVyYWdlIExlbmd0aCIgPSBtZWFuKExlbmd0aCksIkF2ZXJhZ2Ugd2VpZ2h0IiA9IG1lYW4od2VpZ2h0KSwiQXZlcmFnZSBEaWFtZXRlciIgPSBtZWFuKERpYW1ldGVyKSwgICJBdmVyYWdlIFByaWNlIC8gTGVuZ3RoIiA9IG1lYW4oUHJpY2UpL21lYW4oTGVuZ3RoKSwgIkF2ZXJhZ2UgUHJpY2UgLyB3ZWlnaHQiID0gbWVhbihQcmljZSkvbWVhbih3ZWlnaHQpLCAiQXZlcmFnZSBQcmljZSAvIERpYW1ldGVyIiA9IG1lYW4oUHJpY2UpL21lYW4oRGlhbWV0ZXIpKQoKc3VwcGxpZXJfcGxvdF8xCnN1cHBsaWVyX3Bsb3RfMgpzdXBwbGllcl9wbG90XzMKc3VwcGxpZXJfcGxvdF80CmhlYWQoc3VwcGxpZXJfc3RhdGlzdGljcykKCmBgYAoKCgoqKjMpIE9uZSBpbXBvcnRhbnQgcG9pbnQgaW4gZXhwbGFuYXRvcnkgZGF0YSBhbmFseXNpcyBjb25zaXN0cyBpbiBpZGVudGlmeWluZyBwb3RlbnRpYWwgb3V0bGllcnMuIENvdWxkIHlvdSBnaXZlIHBvaW50cyB3aGljaCBhcmUgc3VzcGVjdCByZWdhcmRpbmcgdGhlIE1hdHVyZS5Wb2x1bWUgdmFyaWFibGU/IEdpdmUgdGhlIGNoYXJhY3RlcmlzdGljcyAob3RoZXIgZmVhdHVyZXMpIG9mIHRoZSBvYnNlcnZhdGlvbnMgdGhhdCBzZWVtIHN1c3BzZWN0KioKClRoZXJlIGFyZSBmb3VyIGRhdGEgcG9pbnRzIHdoaWNoIHNlZW0gc3VzcGVjdCAtIHRoZXkgaGF2ZSB0aGUgc2FtZSBjaGFyYWN0ZXJpc3RpY3MgZm9yIERpYW1ldGVyLCB3ZWlnaHQsIG5iLm9mLnBpZWNlcywgSW1wZXJtZWFiaWxpdHksIEZpbmlzaGluZywgUmF3Lk1hdGVyaWFsIGFuZCBNYXR1cmUuVm9sdW1lLiBUaGV5IGRpZmZlciBpbiB0aGVpciBzdXBwbGllciwgcHJpY2UgYW5kIGxlbmd0aC4gVGhlc2Ugc3VnZ2VzdCBzb21lIGVycm9yIGluIGNvbGxhdGluZyB0aGUgZGF0YSAoc3lzdGVtIGVycm9yIC8gZGVmYXVsdCBkYXRhKS4gCgpgYGB7cn0KCk1hdHVyZS5Wb2x1bWVfcGxvdCA8LSBnZ2hpc3RvZ3JhbShyYXdfZGF0YSx4PSJNYXR1cmUuVm9sdW1lIix5PSIuLmNvdW50Li4iLCBjb2xvciA9ICJkYXJrYmx1ZSIsIGZpbGwgPSAibGlnaHRncmV5IikgKyB0aGVtZV9taW5pbWFsKCkKTWF0dXJlLlZvbHVtZV9wbG90CnJhd19kYXRhICU+JSBmaWx0ZXIgKE1hdHVyZS5Wb2x1bWUgPiA2ZSswNSApIAoKYGBgCgoKRm9yIHRoZSByZXN0IG9mIHRoZSBhbmFseXNpcywgdGhlIDQgZGF0YSBwb2ludHMgYWJvdmUgYXJlIGRpc3JlZ2FyZGVkLgoKYGBge3J9CmxpYnJhcnkoZHBseXIpCnJhd19kYXRhIDwtIHJhd19kYXRhICU+JSBmaWx0ZXIgKE1hdHVyZS5Wb2x1bWUgPCA2ZSswNSApCmBgYAoKCldlIHdpbGwgcXVpY2tseSBjaGVjayB0aGF0IHRoZXJlIGFyZSBubyBvdGhlciBub3RpY2VhYmxlIG91dGxpZXJzIC0gdGhpcyBpcyBpbmRlZWQgdGhlIGNhc2UuICAKIApgYGB7cn0KCmNoZWNrXzEgPC0gZ2doaXN0b2dyYW0ocmF3X2RhdGEseD0iTGVuZ3RoIix5PSIuLmNvdW50Li4iLCBjb2xvciA9ICJkYXJrYmx1ZSIsIGZpbGwgPSAibGlnaHRncmV5IikgKyB0aGVtZV9taW5pbWFsKCkKY2hlY2tfMiA8LSBnZ2hpc3RvZ3JhbShyYXdfZGF0YSx4PSJEaWFtZXRlciIseT0iLi5jb3VudC4uIiwgY29sb3IgPSAiZGFya2JsdWUiLCBmaWxsID0gImxpZ2h0Z3JleSIpICsgdGhlbWVfbWluaW1hbCgpCmNoZWNrXzMgPC0gZ2doaXN0b2dyYW0ocmF3X2RhdGEseD0id2VpZ2h0Iix5PSIuLmNvdW50Li4iLCBjb2xvciA9ICJkYXJrYmx1ZSIsIGZpbGwgPSAibGlnaHRncmV5IikgKyB0aGVtZV9taW5pbWFsKCkKY2hlY2tfNCA8LSBnZ2hpc3RvZ3JhbShyYXdfZGF0YSx4PSJuYi5vZi5waWVjZXMiLHk9Ii4uY291bnQuLiIsIGNvbG9yID0gImRhcmtibHVlIiwgZmlsbCA9ICJsaWdodGdyZXkiLGJpbnM9NDApICsgdGhlbWVfbWluaW1hbCgpCgpnZ2FycmFuZ2UoZ2dhcnJhbmdlKGNoZWNrXzEsY2hlY2tfMixuY29sPTIsbnJvdz0xKSxnZ2FycmFuZ2UoY2hlY2tfMyxjaGVja180LG5jb2w9Mixucm93PTEpLG5jb2w9MSxucm93PTIpCgpgYGAKCgoqKjQpIFBlcmZvcm0gYSBQQ0Egb24gdGhlIGRhdGFzZXQgU2NyZXdDYXAsIGV4cGxhaW4gYnJpZWZseSB3aGF0IGFyZSB0aGUgYWltcyBvZiBhIFBDQSBhbmQgaG93IGNhdGVnb3JpY2FsIHZhcmlhYmxlcyBhcmUgaGFuZGxlZD8qKgoKUHJpbmNpcGFsIGNvbXBvbmVudHMgYW5hbHlzaXMgKFBDQSkgaXMgYSB0ZWNobmlxdWUgZm9yIHRha2luZyBoaWdoLWRpbWVuc2lvbmFsIGRhdGEsIGFuZCB1c2luZyB0aGUgZGVwZW5kZW5jaWVzIGJldHdlZW4gdGhlIHZhcmlhYmxlcyB0byByZXByZXNlbnQgaXQgaW4gYSBtb3JlIHRyYWN0YWJsZSwgbG93ZXItZGltZW5zaW9uYWwgZm9ybSwgd2l0aG91dCBsb3NpbmcgdG9vIG11Y2ggaW5mb3JtYXRpb24gLSB3ZSB0cnkgY2FwdHVyZSB0aGUgZXNzZW5jZSBvZiBoaWdoIGRpbWVudGlvbmFsIGRhdGEgaW4gYSBsb3cgZGltZW5zaW9uYWwgcmVwcmVzZW50YXRpb24uIFRoZSBhaW0gb2YgUENBIGlzIHRvIGRyYXcgY29uY2x1c2lvbnMgZnJvbSB0aGUgbGluZWFyIHJlbGF0aW9uc2hpcHMgYmV0d2VlbiB2YXJpYWJsZXMgYnkgZGV0ZWN0aW5nIHRoZSBwcmluY2lwYWwgZGltZW5zaW9ucyBvZiB2YXJpYWJpbGl0eS4gVGhpcyBtYXkgYmUgZm9yIGNvbXByZXNzaW9uLCBkZW5vaXNpbmcsIGRhdGEgY29tcGxldGlvbiwgYW5vbWFseSBkZXRlY3Rpb24gb3IgZm9yIHByZXByb2Nlc3NpbmcgYmVmb3JlIHN1cGVydmlzZWQgbGVhcm5pbmcgKGltcHJvdmUgcGVyZm9ybWFuY2UgLyByZWd1bGFyaXphdGlvbiB0byByZWR1Y2Ugb3ZlcmZpdHRpbmcpLgoKVGhlIGNhdGVnb3JpY2FsIHZhcmlhYmxlcyBjYW5ub3QgYmUgcmVwcmVzZW50ZWQgaW4gdGhlIHNhbWUgd2F5IGFzIHRoZSBzdXBwbGVtZW50YXJ5IHF1YW50aXRhdGl2ZSB2YXJpYWJsZXMgc2luY2UgaXQgaXMgbm90IHBvc3NpYmxlIHRvIGNhbGN1bGF0ZSB0aGUgY29ycmVsYXRpb24gYmV0d2VlbiBhIGNhdGVnb3JpY2FsIHZhcmlhYmxlIGFuZCB0aGUgcHJpbmNpcGFsIGNvbXBvbmVudHMuIFRoZSBjYXRlZ29yaWNhbCB2YXJpYWJsZXMgaGVyZSBhcmUgaGFuZGxlZCBhcyBzdXBwbGVtZXRhcnkgdmFyaWFibGVzIG9uIGEgcHVyZWx5IGlsbHVzdHJhdGl2ZSBiYXNpcyAgLSB0aGV5IGFyZSBub3QgdXNlZCB0byBjYWxjdWxhdGUgdGhlIGRpc3RhbmNlIGJldHdlZW4gaW5pZGl2aWR1YWxzLiBXZSByZXByZXNlbnQgYSBjYXRlZ29yaWNhbCB2YXJpYWJsZSBhdCB0aGUgYmFyeWNlbnRyZSBvZiBhbGwgdGhlIGluZGl2aWR1YWxzIHBvc3Nlc3NpbmcgdGhhdCB2YXJpYWJsZS4gQSBjYXRlZ29yaWNhbCB2YXJpYWJsZSBvbiB0aGUgUENBIHBlcmZvcm1lZCBiZWxvdyBjYW4gdGhlcmVmb3JlIGJlIHJlZ2FyZGVkIGFzIHRoZSBtZWFuIGluZGl2aWR1YWwgb2J0YWluZWQgZnJvbSB0aGUgc2V0IG9mIGluZGl2aWR1YWxzIHdobyBoYXZlIGl0LgoKR2l2ZW4gb3VyIHVsdGltYXRlIGdvYWwgaGVyZSBpcyB0byBleHBsb3JlIGRhdGEgcHJpb3IgdG8gYSBtdWx0aXBsZSByZWdyZXNzaW9uLCBpdCBpcyBhZHZpc2FibGUgdG8gY2hvb3NlIHRoZSBleHBsYW5hdG9yeSB2YXJpYWJsZXMgZm9yIHRoZSByZWdyZXNzaW9uIG1vZGVsIGFzIGFjdGl2ZSB2YXJpYWJsZXMgZm9yIFBDQSwgYW5kIHRvIHByb2plY3QgdGhlIHZhcmlhYmxlIHRvIGJlIGV4cGxhaW5lZCAodGhlIGRlcGVuZGVudCB2YXJpYWJsZSkgYXMgYSBzdXBwbGVtZW50YXJ5IHZhcmlhYmxlLiBUaGlzIGdpdmVzIHNvbWUgaWRlYSBvZiB0aGUgcmVsYXRpb25zaGlwcyBiZXR3ZWVuIGV4cGxhbmF0b3J5IHZhcmlhYmxlcyBhbmQgdGh1cyBvZiB0aGUgbmVlZCB0byBzZWxlY3QgZXhwbGFuYXRvcnkgdmFyaWFibGVzLiBUaGlzIGFsc28gZ2l2ZXMgdXMgYW4gaWRlYSBvZiB0aGUgcXVhbGl0eSBvZiB0aGUgcmVncmVzc2lvbjogaWYgdGhlIGRlcGVuZGVudCB2YXJpYWJsZSBpcyBhcHByb3ByaWF0ZWx5IHByb2plY3RlZCwgaXQgd2lsbCBiZSBhIHdlbGwtZml0dGVkIG1vZGVsLiBUaHVzIHdlIHNlbGVjdCBQcmljZSBhcyBhIHN1cHBsZW1lbnRhcnkgdmFyaWFibGUuIAoKVGhlIGRhdGFzZXQgaW4gdGhpcyBleGVyY2lzZSBjb250YWlucyA2IHN1cHBsZW1lbnRhcnkgdmFyaWFibGVzOgotIDEgcXVhbnRpdGF0aXZlIHZhcmlhYmxlIChQcmljZSkKLSA1IHF1YWxpdGF0aXZlIHZhcmlhYmxlcyAoU3VwcGxpZXIsIFNoYXBlLCBJbXBlcm1lYWJpbGl0eSBhbmQgRmluaXNoaW5nKS4gIAoKCmBgYHtyfQoKcmVzLnBjYSA8LSBQQ0EocmF3X2RhdGEscXVhbGkuc3VwID0gYygxLDUsNiw3LDkpLHF1YW50aS5zdXAgPSAxMCwgZ3JhcGggPSBGQUxTRSkKCmZ2aXpfcGNhX2luZChyZXMucGNhLCBjb2wuaW5kPSJjb3MyIiwgbGFiZWw9YygicXVhbGkiKSwgZ2VvbSA9ICJwb2ludCIsIHRpdGxlID0gIkluZGl2aWR1YWwgZmFjdG9yIG1hcCAoUENBKSIsIGhhYmlsbGFnZSA9ICJub25lIikgKyBzY2FsZV9jb2xvcl9ncmFkaWVudDIobG93PSJsaWdodGJsdWUiLCBtaWQ9ImJsdWUiLCBoaWdoPSJkYXJrYmx1ZSIsIG1pZHBvaW50PTAuNikgKyB0aGVtZV9taW5pbWFsKCkgCnBsb3QuUENBKHJlcy5wY2EsY2hvaXggPSBjKCJpbmQiKSxpbnZpc2libGUgPSBjKCJpbmQiKSkrdGhlbWVfbWluaW1hbCgpCnBsb3QuUENBKHJlcy5wY2EsY2hvaXggPSBjKCJ2YXIiKSkrdGhlbWVfbWluaW1hbCgpCmBgYAoKCgoqKjUpIENvbXB1dGUgdGhlIGNvcnJlbGF0aW9uIG1hdHJpeCBiZXR3ZWVuIHRoZSB2YXJpYWJsZXMgYW5kIGNvbW1lbnQgaXQgd2l0aCByZXNwZWN0IHRvIHRoZSBjb3JyZWxhdGlvbiBjaXJjbGUqKgoKVGhlIGZpcnN0IHRhc2sgaXMgdG8gY2VudGVyIGFuZCBzdGFuZGFyZGl6ZSB0aGUgdmFyaWFibGVzLiBUaGVuIHRoZSBjb3JyZWxhdGlvbiBtYXRyaXggaXMgY29tcHV0ZWQuIEFsbCB2YXJpYWJsZSB2ZWN0b3JzIGFyZSBxdWl0ZSBuZWFyIHRvIHRoZSBib3VuZGFyeSBvZiB0aGUgY29ycmVsYXRpb24gY2lyY2xlIG9uIHRoZSB2YXJpYWJsZXMgcGxvdCAtIHRodXMgdGhlIHZhcmlhYmxlcyBhcmUgcmVsYXRpdmVseSB3ZWxsIHByb2plY3RlZCBvbiB0aGUgMiBkaW1lbnNpb25hbCBzdWJzcGFjZS4gV2Ugbm93IHR1cm4gb3VyIGF0dGVudGlvbiB0byBjb3JyZWxhdGlvbnMgYmV0d2VlbiB2YXJpYWJsZXMuIAoKVGhlIGNvcnJlbGF0aW9ucyBjYW4gYmUgdmlzdWFsaXNlZCB0aHJvdWdoIHRoZSBhbmdsZXMgYmV0d2VlbiB2YXJpYWJsZXMgb24gdGhlIGNvcnJlbGF0aW9uIG1hdHJpeC4gVGhpcyBjYW4gYmUgcmVsYXRlZCB0byB0aGUgY29ycmVsYXRpb24gbWF0cml4OgotIERpYW1ldGVyLCBMZW5ndGggYW5kIHdlaWdodCBleHBvc2UgdmVyeSBzdHJvbmcgY29ycmxlYXRpb246IHRoZSBhbmdsZSBiZXR3ZWVuIHRoZW0gaXMgY2xvc2UgdG8gMCwgc3VnZ2VzdGluZyBjb3JyZWxhdGlvbiBjbG9zZSB0byAxLiBUaGVzZSBhcmUgYWxsIHZlcnkgaGlnaGx5IGNvcnJlbGF0ZWQgdG8gdGhlIGZpcnN0IFByaW5jaXBhbCBDb21wb25lbnQuCi0gVGhlIHRocmVlIHZhcmlhYmxlcyBhYm92ZSBhcmUgYXQgYW4gYW5nbGUgc2lnaHRseSB3aWRlciB0aGFuIGEgcmlnaHQgYW5nbGUgdG8gYm90aCBuYi5vZi5waWVjZXMgYW5kIE1hdHVyZS5Wb2x1bWUgaW4gdGhlIGNpcmxjZSB3aGljaCBzdWdnZXN0cyBzbGlnaHRseSBuZWdhdGl2ZSBjb3JyZWxhdGlvbi4KLSBQcmljZSBpcyBoaWdobGlnaGx5IGNvcnJlbGF0ZCB0byB0aGUgdGhyZWUgdmFyaWFibGVzIGFib3ZlCi0gRXF1YWxseSwgTWF0dXJlLlZvbHVtZSBhbmQgbmIub2YucGllY2VzIGFyZSBhdCBhIHNsaWdodGx5IHdpZGVyIGFuZ2xlIHRoYW4gYSByaWdodCBhbmdsZSB3aGljaCBzdWdnZXN0cyBzbGlnaHRseSBuZWdhdGl2ZSBjb3JyZWxhdGlvbi4KCk1hdHVyZSBWb2x1bWUgYW5kIE51bWJlciBvZiBQaWVjZXMgYXJlIHdlbGwgcHJvamVjdGVkIG9uIHRoZSAybmQgZGltZW5zaW9uYWwgc3Vic3BhY2UgYW5kIHRoZW4gYXJlIG5vdCByZWFsbHkgY29ycmVsYXRlZCB0byBMZW5naHQsIHdlaWdodCwgUHJpY2UgYW5kIERpYW1ldGVyLiBQbHVzLCB3ZSBub3RpY2UgdGhhdCBNYXR1cmUgVm9sdW1lIGFuZCBOdW1iZXIgb2YgUGllY2VzIGFyZSBuZWdhdGl2ZWx5IGNvcnJlbGF0ZWQgd2hpY2ggbWVhbnMgdGhhdCB3aGVuIHRoZSBtb3JlIHBpZWNlcyB3ZSBoYXZlIGZvciBhIHByb2R1Y3QgdGhlIGxlc3MgdGhlIGNvbXBhZ255IGNvbW1hbmQgdGhpcyBraW5kIG9mIHByb2R1Y3QuClRoaXMgY29ycmVsYXRpb25zIGFyZSB3ZWxsIGV4cGxhaW5lZCBpbiB0aGUgY292YXJpYW5jZSBtYXRyaXguIFRoZSBjZWxscyB0aGF0IGNvcnJlc3BvbmQgdG8gYSBjb21iaW5haXNvbiBvZiBoaWdobHkgY29ycmVsYXRlZCBmZWF0dXJlcyBoYXZlIGEgY292IGhpZ2hlciB0aGFuIDAuOSBhbmQgdGhlIGNlbGxzIHRoYXQgY29ycmVzcG9uZCB0byBhIGNvbWJpbmFpc29uIG9mIHVuY29ycmVsYXRlZCAob3J0aG9nb25hbCkgZmVhdHVyZXMgaGF2ZSBhIGNvdiBsb3dlciB0aGFuIDAuMiAtIDAuMy4KClRoZSBQQ0EgZm9jdXNlcyBvbiB0aGUgcmVsYXRpb25zaGlwcyBiZXR3ZWVuIHRoZSBjb250aW51b3VzIHZhcmlhYmxlcy4gSW4gZmFjdCwgdGhlIFBDQSBjb21wdXRlIHRoZSB2ZWN0b3JzIHdoaWNoIGFyZSB0aGUgc3ludGhldGljIHZhcmlhYmxlcyB0aGUgbW9zdCBjb3JyZWxhdGVkIHRvIGFsbCB0aGUgY29udGludW91cyB2YXJpYWJsZXMuIFRoZW4sIGl0cyBwb3NzaWJsZSB0byBzdHVkeSB0aGUgcHJvamVjdGlvbiBvZiB0aGUgb2JzZXJ2YXRpb25zL2ZlYXR1cmVzIG9uIHRoaXMgdmVjdG9ycyBhbmQgZGlzY3VzcyB0aGUgbGluayBiZXR3ZWVuIHRoZW0uIFRoZSBpc3N1ZSBpcyB0aGF0IHRoZSBQQ0EgZG9lcyBub3QgaGFuZGxlIGNhdGVnb3JpY2FsIHZhcmlhYmxlcyB0byB0aGUgY29tcHV0YXRpb24gb2YgdGhlIHN5bnRoZXRpYyB2ZWN0b3JzLgoKTGV0J3Mgbm93IGZvY3VzIG9uIHRoZSBpbmRpdmlkdWFsIGZhY3RvciBtYXAgOiBUaGUgYmFyeWNlbnRyZSByZWxhdGVkIHRvICRJbXBlcm1lYWJpbGl0eSA9IFR5cGUyJCBhbmQgJFJhdy5NYXRlcmlhbCA9IFBTJCBhcmUgbmVhciB0byB0aGUgZmlyc3Qgc3ludGhldGljIGF4ZSB3aGljaCBtZWFucyB0aGF0IHRoaXMgdHdvIGNhdGVnb3JpZXMgVHlwZTIgYW5kIFBTIGFyZSBoaWdobHkgY29ycmVsYXRlZCB0byB0aGlzIGF4ZSBhbmQgdGhlbiwgZ2l2ZW4gdGhlIHByZXZpb3VzIGFuYWx5c2lzIHRvIExlbmdodCwgd2VpZ2h0LCBwcmljZSBhbmQgZGlhbWV0ZXIuIEluIGZhY3QsIGZvciBpbnN0YW5jZSwgd2UgaGF2ZSBzZWVuIHRoYXQgVHlwZSAyIGhhdmUgYSBoaWdoZXIgcHJpY2UgaW4gYXZlcmFnZSB0aGFuIFR5cGUgMS4gV2UgY2FuIHNheSBhbHNvIGZvciBleGFtcGxlIHRoYW4gYSBQUyBwcm9kdWN0IGlzIHJlbGF0ZWQgdG8gYSBoaWdoIGRpYW1ldGVyLgoKCgoKYGBge3J9CmRvbiA8LSBhcy5tYXRyaXgocmF3X2RhdGFbLC1jKDEsNSw2LDcsOSwxMCldKSAlPiUgc2NhbGUoKQpkb25fY29ycmVsYXRpb24gPC0gY29yKGRvbikKZG9uX2NvcnJlbGF0aW9uCnBsb3QuUENBKHJlcy5wY2EsY2hvaXggPSBjKCJ2YXIiKSkrdGhlbWVfbWluaW1hbCgpCmBgYAoKKio2KSBPbiB3aGF0IGtpbmQgb2YgcmVsYXRpb25zaGlwIFBDQSBmb2N1c2VzPyBJcyBpdCBhIHByb2JsZW0/KioKClBDQSBmb2N1c2VzIG9uIHRoZSBsaW5lYXIgcmVsYXRpb25zaGlwcyBiZXR3ZWVuIGNvbnRpbnVvdXMgdmFyaWFibGVzLiBHaXZlbiBjb21wbGV4IGxpbmtzIGFsc28gZXhpc3QsIHN1Y2ggYXMgcXVhZHJhdGljIHJlbGF0aW9uc2hpcHMsIGxvZ2FyaXRobWljcywgZXhwb25lbnRpYWwgZnVuY3Rpb25zLCBhbmQgc28gZm9ydGgsIHRoaXMgbWF5IHNlZW0gcmVzdHJpY3RpdmUsIGJ1dCBpbiBwcmFjdGljZSBtYW55IHJlbGF0aW9uc2hpcHMgY2FuIGJlIGNvbnNpZGVyZWQgbGluZWFyLCBhdCBsZWFzdCBmb3IgYW4gaW5pdGlhbCBhcHByb3hpbWF0aW9uLiBIb3dldmVyLCB0aGVyZSBpcyBvYnZpb3VzbHkgbm9uLWxpbmVhciBkYXRhc2V0cyBmb3Igd2hpY2ggUENBIHdpbGwgaGF2ZSBwaXRmYWxscyAoZS5nLiBzcGlyYWwgZGF0YXNldCkuIEZ1cnRoZXJtb3JlLCBpbiBQQ0EgY2F0ZWdvcmljYWwgdmFyaWFibGVzIGNhbm5vdCBiZSBhY3RpdmUgdmFyaWFibGVzLCB3aGljaCBjYW4gYmUgcmVzdHJpY3RpdmUuIAoKKio3KSBDb21tZW50IHRoZSBQQ0Egb3V0cHV0cyoqCgoqQ29tbWVudCB0aGUgcG9zaXRpb24gb2YgdGhlIGNhdGVnb3JpZXMgSW1wZXJtZWFiaWxpdHk9dHlwZSAyIGFuZCBSYXcuTWF0ZXJpYWw9UFMuKgoKVGhlIGNvb3JkaW5hdGVzIGZvciBUeXBlIDIgYXJlICgzLjMwNDMwMTYyICwgMC4wMDIwMDIzNDIyKSBmb3IgdGhlIGZpcnN0IHR3byBwcmluY2lwYWwgY29tcG9uZW50cyAKVGhlIGNvb3JkaW5hdGUgZm9yIFBTIGFyZSAoMi42OTA4NDUwNyAtMC4yNTM5MTk5NTM4KSBmb3IgdGhlIGZpcnN0IHR3byBwcmluY2lwYWwgY29tcG9uZW50cyAKCkJvdGggY2F0ZWdvcmllcyBoYXZlIGEgaGlnaCBjb29yZGluYXRlIGZvciB0aGUgZmlyc3QgcHJpbmNpcGFsIGNvbXBvbmVudC4gR2l2ZW4gdGhlIGNvcnJlbGF0aW9uIGNpcmNsZSBzaG93cyBoaWdoIGNvcnJlbGF0aW9uIGJldHdlZW4gdGhlIGZpcnN0IGNvbXBvbmVudCBhbmQgcHJpY2UsIGRpYW1ldGVyLCBsZW5ndGggYW5kIHdlaWdodCwgdGhpcyBzdWdnZXN0IFR5cGUgMiBhbmQgUFMgaGF2ZSBoaWdoIHZhbHVlcyBmb3IgdGhlc2UgdmFyaWFibGVzLiAKCmBgYHtyfQpyZXMucGNhJHF1YWxpLnN1cCRjb29yZApgYGAKCipDb21tZW50IHRoZSBwZXJjZW50YWdlIG9mIGluZXJ0aWEqCgpCZWxvdyB3ZSBzZWUgdGhlIHBlcmNlbnRhZ2Ugb2YgaW5lcnRpYSBleHBsYWluZWQgYnkgZWFjaCBjb21wb25lbnQuIAoKCmBgYHtyfQpyZXMucGNhJGVpZwpgYGAKCgoKCmBgYHtyfQpiYXJwbG90KHJlcy5wY2EkZWlnWywyXSwgbmFtZXMuYXJnID0gMTpucm93KHJlcy5wY2EkZWlnKSkKZHJhd24gPC0gYygiOTAiLCAiODkiLCAiMTY0IiwgIjE2MSIsICIxNjMiLCAiMTMxIikKcGxvdC5QQ0EocmVzLnBjYSwgc2VsZWN0ID0gImNvczIgNSIsIGF4ZXMgPSAxOjIsIGNob2l4ID0gJ2luZCcsIGludmlzaWJsZSA9ICdxdWFsaScsIHRpdGxlID0gJycpCndpbGtzLnAgPC0gc3RydWN0dXJlKGMoMS4zOTkzNjMyNDg0ODAwNWUtMjcsIDEuMDIwNzI5MTI5ODQ0MDJlLTIyLCAyLjAxMDg4MTMyNzMyMDY3ZS0xMSwgCjMuMzcxNzQ1Njg5OTc4MThlLTA3LCAwLjM5NDU0NjE3NjQwNTExOSksIC5OYW1lcyA9IGMoIkltcGVybWVhYmlsaXR5IiwgIlJhdy5NYXRlcmlhbCIsICJTaGFwZSIsICJTdXBwbGllciIsICJGaW5pc2hpbmciKSkKd2lsa3MucAoKc2FtcGxlID0gc2FtcGxlKHJvd25hbWVzKHJlcy5wY2EkY2FsbCRYKSwgbGVuZ3RoKHJvd25hbWVzKHJlcy5wY2EkY2FsbCRYKSkpCnJlcy5wY2EkY2FsbCRYID0gcmVzLnBjYSRjYWxsJFhbc2FtcGxlLF0KcmVzLnBjYSRpbmQkY29vcmQgPSByZXMucGNhJGluZCRjb29yZFtzYW1wbGVbIXNhbXBsZSAlaW4lIHJvd25hbWVzKHJlcy5wY2EkaW5kLnN1cCRjb29yZCldLF0KcmVzLnBjYSRpbmQuc3VwJGNvb3JkID0gcmVzLnBjYSRpbmQuc3VwJGNvb3JkW3NhbXBsZVtzYW1wbGUgJWluJSByb3duYW1lcyhyZXMucGNhJGluZC5zdXAkY29vcmQpXSxdCgpkcmF3biA8LWMoIjkwIiwgIjg5IiwgIjE2NCIsICIxNjEiLCAiMTYzIiwgIjEzMSIpCmhhYiA8LSJJbXBlcm1lYWJpbGl0eSIKcGxvdGVsbGlwc2VzKHJlcy5wY2EsIGF4ZXMgPSAxOjIsIGludmlzaWJsZSA9ICdxdWFsaScsIHNlbGVjdCA9ICJjb3MyIDUiLCBrZWVwdmFyID0gaGFiLCB0aXRsZSA9ICcnKQoKZHJhd24gPC1jKCJMZW5ndGgiLCAiRGlhbWV0ZXIiLCAid2VpZ2h0IiwgIm5iLm9mLnBpZWNlcyIsICJQcmljZSIpCnBsb3QuUENBKHJlcy5wY2EsIHNlbGVjdCA9ICJjb3MyIDUiLCBheGVzID0gMToyLCBjaG9peCA9ICd2YXInLCB0aXRsZSA9ICcnKQoKZHJhd24gPC0gYygiVHlwZSAxIiwgIlR5cGUgMiIsICJTdXBwbGllciBBIiwgIlBTIiwgIlBQIiwgIlNoYXBlIDIiLCAiU2hhcGUgMyIsICJTaGFwZSAxIiwgIkxhY3F1ZXJpbmciLCAiU3VwcGxpZXIgQiIsICJTdXBwbGllciBDIiwiSG90IFByaW50aW5nIikKcGxvdC5QQ0EocmVzLnBjYSwgc2VsZWN0ID0gImNvczIgNSIsIGF4ZXMgPSAxOjIsIGNob2l4ID0gJ2luZCcsIGludmlzaWJsZSA9IGMoJ2luZCcsICdpbmQuc3VwJyksIHRpdGxlID0gJycpCgoKCnJlcy5wY2EgPC0gUENBKHJhd19kYXRhLHF1YWxpLnN1cCA9IGMoMSw1LDYsNyw5KSxxdWFudGkuc3VwID0gMTAsIG5jcD0zKSAjbmNwID0gMwpyZXMuaGNwYyA8LSBIQ1BDKHJlcy5wY2EsIG5iLmNsdXN0ID0gLTEKICAgICAgICAgICAgICAgICwgZ3JhcGggPSBGQUxTRSkKCmRyYXduIDwtIGMoIjE2OCIpCnBsb3QuSENQQyhyZXMuaGNwYywgY2hvaWNlID0gJ21hcCcsIGRyYXcudHJlZSA9IEZBTFNFLCBzZWxlY3QgPSAiY29zMiA1IiwgdGl0bGUgPSAnJykKZGltZGVzYyhyZXMucGNhLCBheGVzID0gMToxKQpyZXMuaGNwYyRkZXNjLnZhcgoKYGBgCgpGaXNoZXIgdGVzdApWYXJpYW5jZQoKCmBgYHtyfQoKZnZpel9uYmNsdXN0KGRvbiwga21lYW5zLCBtZXRob2QgPSAid3NzIikgKyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAzLCBsaW5ldHlwZSA9IDIpCgpgYGAKCgoqQ29tbWVudHMgdGhlIHJlc3VsdHMgYW5kIGRlc2NyaWJlIHByZWNpc2VseSBvbmUgY2x1c3RlciogLS0gQWRkIEZpc2hlciBUZXN0CgpUaGUgY2x1c3RlciAxIGlzIG1hZGUgb2YgaW5kaXZpZHVhbHMgc2hhcmluZyA6Ci0gaGlnaCB2YWx1ZXMgZm9yIHRoZSB2YXJpYWJsZSBNYXR1cmUuVm9sdW1lLiAKLSBsb3cgdmFsdWVzIGZvciB0aGUgdmFyaWFibGVzIG5iLm9mLnBpZWNlcywgUHJpY2UsIHdlaWdodCwgTGVuZ3RoIGFuZCBEaWFtZXRlciAodmFyaWFibGVzIGFyZSBzb3J0ZWQgZnJvbSB0aGUgd2Vha2VzdCkuCgpUaGUgY2x1c3RlciAyIGlzIG1hZGUgb2YgaW5kaXZpZHVhbHMgc2hhcmluZyA6Ci0gaGlnaCB2YWx1ZXMgZm9yIHRoZSB2YXJpYWJsZSBuYi5vZi5waWVjZXMuIAotIGxvdyB2YWx1ZXMgZm9yIHRoZSB2YXJpYWJsZXMgTWF0dXJlLlZvbHVtZSwgRGlhbWV0ZXIsIExlbmd0aCwgd2VpZ2h0IGFuZCBQcmljZSAodmFyaWFibGVzIGFyZSBzb3J0ZWQgZnJvbSB0aGUgd2Vha2VzdCkuCgpUaGUgY2x1c3RlciAzIGlzIG1hZGUgb2YgaW5kaXZpZHVhbHMgc3VjaCBhcyA4OSwgOTAsIDEzMSwgMTYxLCAxNjMgYW5kIDE2NC4gVGhpcyBncm91cCBpcyBjaGFyYWN0ZXJpemVkIGJ5IDoKLSBoaWdoIHZhbHVlcyBmb3IgdGhlIHZhcmlhYmxlcyBMZW5ndGgsIERpYW1ldGVyLCB3ZWlnaHQgYW5kIFByaWNlICh2YXJpYWJsZXMgYXJlIHNvcnRlZCBmcm9tIHRoZSBzdHJvbmdlc3QpLgotIGxvdyB2YWx1ZXMgZm9yIHRoZSB2YXJpYWJsZXMgbmIub2YucGllY2VzIGFuZCBNYXR1cmUuVm9sdW1lICh2YXJpYWJsZXMgYXJlIHNvcnRlZCBmcm9tIHRoZSB3ZWFrZXN0KS4KCgoqSWYgc29tZW9uZSBhc2sgeW91IHdoeSB5b3UgaGF2ZSBzZWxlY3RlZCBrIGNvbXBvbmVudHMgYW5kIG5vdCBrICsgMSBvciBrIOKIkiAxLCB3aGF0IGlzIHlvdXIgYW5zd2VyPyAoY291bGQgeW91IHN1Z2dlc3QgYSBzdHJhdGVneSB0byBhc3Nlc3MgdGhlIHN0YWJpbGl0eSBvZiB0aGUgYXBwcm9hY2g/IC0gYXJlIHRoZXJlIG1hbnkgZGlmZmVyZW5jZXMgYmV0d2VlbiB0aGUgY2x1c3RlcmluZyBvYnRhaW5lZCBvbiBrIGNvbXBvbmVudHMgb3Igb24gdGhlIGluaXRpYWwgZGF0YSkqCgpgYGB7cn0KcmVzLnBjYSA8LSBQQ0EocmF3X2RhdGEscXVhbGkuc3VwID0gYygxLDUsNiw3LDkpLHF1YW50aS5zdXAgPSAxMCxuY3A9NCkKcmVzLmhjcGMgPC0gSENQQyhyZXMucGNhLCBuYi5jbHVzdCA9IC0xKQpyZXMucGNhIDwtIFBDQShyYXdfZGF0YSxxdWFsaS5zdXAgPSBjKDEsNSw2LDcsOSkscXVhbnRpLnN1cCA9IDEwLG5jcD0zKQpyZXMuaGNwYyA8LSBIQ1BDKHJlcy5wY2EsIG5iLmNsdXN0ID0gLTEpCnJlcy5wY2EgPC0gUENBKHJhd19kYXRhLHF1YWxpLnN1cCA9IGMoMSw1LDYsNyw5KSxxdWFudGkuc3VwID0gMTAsbmNwPTIpCnJlcy5oY3BjIDwtIEhDUEMocmVzLnBjYSwgbmIuY2x1c3QgPSAtMSkKYGBgCmBgYHtyfQpyZXMuaGNwYyA8LSBIQ1BDKHJlcy5wY2EsIG5iLmNsdXN0ID0gLTEsIGdyYXBoID0gRkFMU0UpCgpgYGAKCiAKYGBge3J9CnJlcy5oY3BjIDwtIEhDUEMocmVzLnBjYSwgbmIuY2x1c3QgPSAtMSwgZ3JhcGggPSBGQUxTRSkKcmVzLmhjcGMKcGxvdC5IQ1BDKHJlcy5oY3BjLCBjaG9pY2UgPSAnbWFwJywgZHJhdy50cmVlID0gRkFMU0UsIHRpdGxlID0gJycsIHNlbGVjdD1jKCIxMiIpKQoKCnJlcy5wY2EgPC0gUENBKHJhd19kYXRhLHF1YWxpLnN1cCA9IGMoMSw1LDYsNyw5KSxxdWFudGkuc3VwID0gMTAsbmNwPTMpCnJlcy5oY3BjIDwtIEhDUEMocmVzLnBjYSwgbmIuY2x1c3QgPSAtMSwgZ3JhcGggPSBGQUxTRSkKcmVzLmhjcGMKCmBgYAoKQ2hhcmFjdGVyaXphdGlvbiBvZiBlYWNoIHN1cHBsaWVyCgoKYGBge3J9CmNhdGRlcyhyYXdfZGF0YSwgbnVtLnZhcj0xKQpjYXRkZXMocmF3X2RhdGEsIG51bS52YXI9NSkKCmNhdGRlcyhyYXdfZGF0YSwgbnVtLnZhcj02KQoKCmBgYAoKCmBgYHtyfQpyZXMuZmFtZCA8LSBGQU1EIChyYXdfZGF0YSwgbmNwID0gNSwgZ3JhcGggPSBUUlVFLCBzdXAudmFyID0gIGMoMTApLCBheGVzID0gYygxLDIpLCByb3cudyA9IE5VTEwsIHRhYi5jb21wID0gTlVMTCkKCnJlcy5oY3BjLmZhbWQgPC0gSENQQyhyZXMuZmFtZCwgbmIuY2x1c3QgPSAtMQogICAgICAgICAgICAgICAgLCBncmFwaCA9IFRSVUUpCgpwbG90LkhDUEMocmVzLmhjcGMuZmFtZCwgY2hvaWNlID0gJ21hcCcsIGRyYXcudHJlZSA9IEZBTFNFLCBzZWxlY3QgPSBjKDEsMTApLCB0aXRsZSA9ICcnKQoKcmF3X2RhdGFfY2x1c3QgPC0gcmVzLmhjcGMuZmFtZCRkYXRhLmNsdXN0CgpyZXMuZmFtZF8yIDwtIEZBTUQgKHJhd19kYXRhX2NsdXN0LCBuY3AgPSA2LCBncmFwaCA9IFRSVUUsIHN1cC52YXIgPSAgYygxLDUsNywxMCksIGF4ZXMgPSBjKDEsMiksIHJvdy53ID0gTlVMTCwgdGFiLmNvbXAgPSBOVUxMKQpyZXMuZmFtZF8yJGVpZwoKY29vcmRpbmF0ZXMgPC0gYXMuZGF0YS5mcmFtZShyZXMuZmFtZF8yJGluZCRjb29yZCkKY29vcmRpbmF0ZXMkUHJpY2UgPC0gcmF3X2RhdGFfY2x1c3QkUHJpY2UKY29vcmRpbmF0ZXMKCmZpdCA8LSBsbShQcmljZSB+IGNvb3JkaW5hdGVzJERpbS4xICsgY29vcmRpbmF0ZXMkRGltLjIgKyBjb29yZGluYXRlcyREaW0uMyArIGNvb3JkaW5hdGVzJERpbS40ICsgY29vcmRpbmF0ZXMkRGltLjUgKyBjb29yZGluYXRlcyREaW0uNixyYXdfZGF0YV9jbHVzdCkKcCA8LSByYXdfZGF0YV9jbHVzdFsxLF0KCgpwcmVkaWN0X3ByaWNlIDwtIGZ1bmN0aW9uICh4KSB7CiAgZml0IDwtICBsbShQcmljZSB+IGNvb3JkaW5hdGVzJERpbS4xICsgY29vcmRpbmF0ZXMkRGltLjIgKyBjb29yZGluYXRlcyREaW0uMyArIGNvb3JkaW5hdGVzJERpbS40ICsgY29vcmRpbmF0ZXMkRGltLjUgKyBjb29yZGluYXRlcyREaW0uNiwgcmF3X2RhdGFfY2x1c3QpCiAgcCA8LSBhcy5kYXRhLmZyYW1lKHByZWRpY3QuRkFNRChyZXMuZmFtZF8yLHgpJGNvb3JkKSAKICBwIDwtIHAgJT4lIHJlbmFtZShEaW0xID0gJ0RpbSAxJywgRGltMiA9ICdEaW0gMicsRGltMyA9ICdEaW0gMycsRGltNCA9ICdEaW0gNCcsIERpbTUgPSAnRGltIDUnLCBEaW02ID0gJ0RpbSA2JykKICByZXR1cm4ocHJlZGljdChmaXQscCkpCn0KCgpwZXJjZW50YWdlX2xlYXJuaW5nIDwtIDAuODAKCmxlYXJuaW5nX3NldCA8LSBzYW1wbGVfbihyYXdfZGF0YV9jbHVzdCwgcGVyY2VudGFnZV9sZWFybmluZyAqIGRpbShyYXdfZGF0YV9jbHVzdClbMV0pCnJlcy5mYW1kX2xlYXJuaW5nIDwtIEZBTUQgKGxlYXJuaW5nX3NldCwgbmNwID0gNSwgZ3JhcGggPSBUUlVFLCBzdXAudmFyID0gIGMoMSw1LDcsMTApLCBheGVzID0gYygxLDIpLCByb3cudyA9IE5VTEwsIHRhYi5jb21wID0gTlVMTCkKcmVzLmhjcGMuZmFtZF9sZWFybmluZyA8LSBIQ1BDKHJlcy5mYW1kX2xlYXJuaW5nLCBuYi5jbHVzdCA9IC0xCiAgICAgICAgICAgICAgICAsIGdyYXBoID0gVFJVRSkKCnJlcy5mYW1kX2xlYXJuaW5nXzIgPC0gRkFNRCAobGVhcm5pbmdfc2V0X2NsdXN0LCBuY3AgPSA2LCBncmFwaCA9IFRSVUUsIHN1cC52YXIgPSAgYygxLDUsNywxMCksIGF4ZXMgPSBjKDEsMiksIHJvdy53ID0gTlVMTCwgdGFiLmNvbXAgPSBOVUxMKQoKbGVhcm5pbmdfc2V0X2NsdXN0IDwtIHJlcy5oY3BjLmZhbWRfbGVhcm5pbmckZGF0YS5jbHVzdApjb29yZGluYXRlc19sZWFybmluZyA8LSBhcy5kYXRhLmZyYW1lKHJlcy5mYW1kX2xlYXJuaW5nXzIkaW5kJGNvb3JkKQpjb29yZGluYXRlc19sZWFybmluZyRQcmljZSA8LSBsZWFybmluZ19zZXRfY2x1c3QkUHJpY2UKY29vcmRpbmF0ZXNfbGVhcm5pbmcKCnByZWRpY3RfbmV3X3ByaWNlIDwtIGZ1bmN0aW9uICh4KSB7CiAgZml0IDwtICBsbShQcmljZSB+IGNvb3JkaW5hdGVzX2xlYXJuaW5nJERpbS4xICsgY29vcmRpbmF0ZXNfbGVhcm5pbmckRGltLjIgKyBjb29yZGluYXRlc19sZWFybmluZyREaW0uMyArIGNvb3JkaW5hdGVzX2xlYXJuaW5nJERpbS40ICsgY29vcmRpbmF0ZXNfbGVhcm5pbmckRGltLjUgKyBjb29yZGluYXRlc19sZWFybmluZyREaW0uNiwgbGVhcm5pbmdfc2V0X2NsdXN0KQogIHAgPC0gYXMuZGF0YS5mcmFtZShwcmVkaWN0LkZBTUQocmVzLmZhbWRfMix4KSRjb29yZCkgCiAgcCA8LSBwICU+JSByZW5hbWUoRGltMSA9ICdEaW0gMScsIERpbTIgPSAnRGltIDInLERpbTMgPSAnRGltIDMnLERpbTQgPSAnRGltIDQnLCBEaW01ID0gJ0RpbSA1JywgRGltNiA9ICdEaW0gNicpCiAgcmV0dXJuKHByZWRpY3QoZml0LHApKQp9CgoKYGBgCgoKYGBge3J9CgpzdW1tYXJ5KHJlcy5oY3BjLmZhbWQpCgpyZXMuaGNwYy5mYW1kJGNhbGwkWCREaW0uMQoKCmBgYAoK